﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceProcess;
using System.Timers;
using Microsoft.Win32;
using System.Security.Permissions;
using System.Threading;


namespace ProDeletorGUI
{
    public partial class ProDeletorGUI : Form
    {
        TaskSettings taskSettings;
        TaskList taskList;
        ServiceController sc;
        string controlFile;
        

        public ProDeletorGUI()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            sc = new ServiceController("ProDeletor");
            SetDisplay(sc);
            taskList = new TaskList();
            taskSettings = new TaskSettings();
            propertyGrid1.Enabled = false;
            timer1.Interval = 2000;
            timer1.Tick += new EventHandler(timer1_Tick);
            timer1.Enabled = true;
            timer1.Start();
            
        }

        void timer1_Tick(object sender, EventArgs e)
        {
            SetDisplay(sc);
        }

        private void openControlFile(string fileName)
        {
            listBox1.Items.Clear();
            taskList = new TaskList();
            taskList.readControlFile(fileName);
            taskSettings = new TaskSettings();
            foreach (Task taskSet in taskList.taskList)
            {
                listBox1.Items.Add(taskSet.Name);
            }
            if (listBox1.Items.Count > 0)
            {
                listBox1.SelectedIndex = 0;
                propertyGrid1.Enabled = true;
            }
            else propertyGrid1.Enabled = false;
        }

        private void SetDisplay(ServiceController sc)
        {
            sc.Refresh();
            if (sc.Status == ServiceControllerStatus.Running)
            {
                serviceStatus.Text = "ProDeletor service running";
                startService.Enabled = false;
                stopService.Enabled = true;
            }
            if (sc.Status == ServiceControllerStatus.Stopped)
            {
                serviceStatus.Text = "ProDeletor service is stopped";
                startService.Enabled = true;
                stopService.Enabled = false;
            }
        } 

        private void newTask_Click(object sender, EventArgs e)
        {
            Task newTask = new Task();
            newTask.Mode = "Last accessed";
            newTask.Name = "New task";
            taskList.taskList.Add(newTask);
            listBox1.Items.Add( newTask.Name);
            listBox1.SelectedIndex = listBox1.Items.Count - 1;
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            int index = listBox1.SelectedIndex;

            taskSettings.Name = taskList.taskList[index].Name;
            taskSettings.Logging = taskList.taskList[index].Logging;
            taskSettings.LogPath = taskList.taskList[index].LogPath;
            taskSettings.KeepMinutes = taskList.taskList[index].KeepMinutes;
            taskSettings.KeepHour = taskList.taskList[index].KeepHours;
            taskSettings.KeepDays = taskList.taskList[index].KeepDays;
            taskSettings.Hour = taskList.taskList[index].Hour;
            taskSettings.Folder = taskList.taskList[index].Folder;
            taskSettings.Minute = taskList.taskList[index].Minute;
            taskSettings.Monday = taskList.taskList[index].Monday;
            taskSettings.Tuesday = taskList.taskList[index].Tuesday;
            taskSettings.Wednesday = taskList.taskList[index].Wednesday;
            taskSettings.Thursday = taskList.taskList[index].Thursday;
            taskSettings.Friday = taskList.taskList[index].Friday;
            taskSettings.Saturday = taskList.taskList[index].Saturday;
            taskSettings.Sunday = taskList.taskList[index].Sunday;
            taskSettings.TestMode = taskList.taskList[index].TestMode;
            taskSettings.Recursive = taskList.taskList[index].Recursive;
            taskSettings.DeleteEmptyFolders = taskList.taskList[index].EmptyFolder;
            taskSettings.Archive = taskList.taskList[index].Archive;
            taskSettings.ArchiveFolder = taskList.taskList[index].ArchiveFolder;
            taskSettings.Mode = taskList.taskList[index].Mode;
            propertyGrid1.SelectedObject = taskSettings;
            propertyGrid1.Enabled = true;
        }

        void propertyGrid1_PropertyValueChanged(object s, System.Windows.Forms.PropertyValueChangedEventArgs e)
        {
            int index = listBox1.SelectedIndex;
            taskList.taskList[index].Name = taskSettings.Name;
            taskList.taskList[index].EmptyFolder = taskSettings.DeleteEmptyFolders;
            taskList.taskList[index].Folder = taskSettings.Folder;
            taskList.taskList[index].Hour = taskSettings.Hour;
            taskList.taskList[index].KeepDays = taskSettings.KeepDays;
            taskList.taskList[index].KeepHours = taskSettings.KeepHour;
            taskList.taskList[index].KeepMinutes = taskSettings.KeepMinutes;
            taskList.taskList[index].Logging = taskSettings.Logging;
            taskList.taskList[index].LogPath = taskSettings.LogPath;
            taskList.taskList[index].ArchiveFolder = taskSettings.ArchiveFolder;
            taskList.taskList[index].Archive = taskSettings.Archive;
            taskList.taskList[index].Monday = taskSettings.Monday;
            taskList.taskList[index].Tuesday = taskSettings.Tuesday;
            taskList.taskList[index].Wednesday = taskSettings.Wednesday;
            taskList.taskList[index].Thursday = taskSettings.Thursday;
            taskList.taskList[index].Friday = taskSettings.Friday;
            taskList.taskList[index].Saturday = taskSettings.Saturday;
            taskList.taskList[index].Sunday = taskSettings.Sunday;
            taskList.taskList[index].Recursive = taskSettings.Recursive;
            taskList.taskList[index].TestMode = taskSettings.TestMode;
            taskList.taskList[index].Minute = taskSettings.Minute;
            taskList.taskList[index].Mode = taskSettings.Mode;

            listBox1.Items.Clear();
            foreach (Task taskSet in taskList.taskList)
            {
                listBox1.Items.Add(taskSet.Name);
            }
            listBox1.SelectedIndex = index;
        }

        private void removeTask_Click(object sender, EventArgs e)
        {
            int index = listBox1.SelectedIndex;
            if(index>-1)
                taskList.taskList.Remove(taskList.taskList[index]);
            listBox1.Items.Clear();
            foreach (Task taskSet in taskList.taskList)
            {
                listBox1.Items.Add(taskSet.Name);
            }
            if (listBox1.Items.Count > 0)
                listBox1.SelectedIndex = 0;
            else
            {
                propertyGrid1.Enabled = false;
            }
        }

        private void query_Click(object sender, EventArgs e)
        {
            SetDisplay(sc);
        }

        private void startService_Click(object sender, EventArgs e)
        {
            try
            {
                sc.Start();
                sc.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(3));
            }
            catch
            {
                MessageBox.Show("Cannot start service, check your administrative privilege.", "ProDeletor Service", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            SetDisplay(sc);
        }

        private void stopService_Click(object sender, EventArgs e)
        {
            try
            {
                sc.Stop();
                sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(3));
            }
            catch
            {
                MessageBox.Show("Cannot stop service, check your administrative privilege.", "ProDeletor Service", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            SetDisplay(sc);
        }

        private void savePlan_Click(object sender, EventArgs e)
        {
            saveFileDialog1.DefaultExt = ".xml";
            saveFileDialog1.FileName = "*.xml";
            saveFileDialog1.Filter = "ProDeletor XML-files(*.XML)|*.xml";
            DialogResult result = saveFileDialog1.ShowDialog();
            
            if (result == DialogResult.OK)
            {
                string fileName = saveFileDialog1.FileName;
                taskList.writeControlFile(fileName);
            }
        }

        private void openPlan_Click(object sender, EventArgs e)
        {
            openFileDialog1.FileName = "*.xml";
            openFileDialog1.Filter = "ProDeletor XML-files(*.XML)|*.xml";
            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                string fileName = openFileDialog1.FileName;
                openControlFile(fileName);
            }
        }

        private void newPlan_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            taskList = new TaskList();
            propertyGrid1.Enabled = false;
        }

        private void inProduction_Click(object sender, EventArgs e)
        {
            //TODO: stop service, copy tasks to prod and start service
            
            if (listBox1.Items.Count < 1)
                return;
            //check if every needed fields are specified
            if (!validateTasks())
                return;
            RegistryKey registryKey = Registry.LocalMachine;
            RegistryPermission registryAccess = new RegistryPermission(
            RegistryPermissionAccess.Write | RegistryPermissionAccess.Read,
                @"HKEY_LOCAL_MACHINE\SOFTWARE\ProDeletor");
            try
            {
                RegistryKey localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ?
                    RegistryView.Registry64 : RegistryView.Registry32);
                RegistryKey regKey = localMachine.OpenSubKey(@"SOFTWARE\ProDeletor");
                
                controlFile = regKey.GetValue("ControlFile").ToString();
                //MessageBox.Show("Value: " + controlFile, "Test Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch
            {
                MessageBox.Show("Cannot read registrykey 'HKLM/SOFTWARE/ProDeletor", "Registry read error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            try
            {
                if (sc.Status == ServiceControllerStatus.Running)
                {
                    sc.Stop();
                    sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(5));
                }
                Thread.Sleep(1500);
                taskList.writeControlFile(controlFile);
                if(sc.Status==ServiceControllerStatus.Stopped)
                    sc.Start();
                sc.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(5));
                MessageBox.Show("Plan exported to production", "Export succeed", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch
            {
                MessageBox.Show("Export to production failed, check your administrative privileges.", "Export failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        private bool validateTasks()
        {
            string errorText="";
            foreach (Task task in taskList.taskList)
            {
                if (task.Folder == null || task.Folder.Length < 2)
                    errorText += task.Name + ": Folder not specified\n";
                if (task.LogPath == null || task.LogPath.Length < 2)
                    errorText += task.Name + ": LogPath not specified\n";
                if(task.Archive)
                    if (task.ArchiveFolder == null || task.ArchiveFolder.Length < 2)
                        errorText += task.Name + ": Archive folder not specified\n";
            }
            if (errorText.Length > 0)
            {
                MessageBox.Show("Please fill the following fields.\n\n" + errorText, "Check fields", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            return true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            AboutBox1 aboutBox = new AboutBox1();
            aboutBox.ShowDialog();
        }
    }
}
